home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Creative Computers
/
Creative Computers CD-ROM, Volume 1 (Legendary Design Technologies, Inc.)(1994).iso
/
shareware
/
intuition
/
yak_1.57
/
source
/
handler.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-11-17
|
14KB
|
566 lines
/*
* handler.c
*
* Routines to set up handler.
* Part of Yak.
*
* Martin W. Scott, 9/92.
*/
#include <exec/types.h>
#include <exec/exec.h>
#include <hardware/custom.h>
#include <hardware/dmabits.h>
#include <devices/console.h>
#include <devices/input.h>
#include <devices/inputevent.h>
#include <libraries/commodities.h>
#include <graphics/gfxbase.h>
#include <graphics/gfxmacros.h>
#include <graphics/displayinfo.h>
#include <intuition/intuition.h>
#include <intuition/intuitionbase.h>
#include <proto/exec.h>
#include <proto/dos.h>
#include <proto/layers.h>
#include <proto/graphics.h>
#include <proto/intuition.h>
#include <proto/commodities.h>
#include <string.h>
#include "yak.h"
#include "beep.h"
static void __inline TurnMouseOn (void);
static void __inline TurnMouseOff (void);
static void __regargs IntuiOp (void (*routine) (APTR), APTR parameter);
static void __regargs PopToFront (struct Window *win);
static struct Window *WindowUnderMouse (void);
static BOOL __regargs StrGadgetActive (struct Window *w);
extern struct Custom __far custom;
#define REBLANKCOUNT 10 /* how long to wait to reblank mouse */
void (*intui_routine) (APTR); /* for intui_op's */
APTR intui_parameter;
CxObj *clickobj;
ULONG clicksigflag, intuiopsigflag;
static BYTE clicksigbit, intuiopsigbit = -1;
static struct Task *thistask;
static BOOL misspop;
/* for screen click-to-back */
void __stdargs
MyScreenToBack (struct Screen *scr)
{
struct Screen *ns = scr->NextScreen;
struct Window *win;
if (!ns)
ns = IntuitionBase->FirstScreen;
if (ns != scr)
{
ScreenToBack (scr);
if (scractivate && ns)
{
win = WindowUnderMouse();
if (win)
ActivateWindow (win);
else
if (ns->FirstWindow)
ActivateWindow (ns->FirstWindow);
}
}
}
/* Stub for Intuition routines - passes request on to main task.
* DO NOT CALL WHILE FORBID()ING!
* Thanks to Eddy Carroll for this.
*/
#define WTB(win) IntuiOp(WindowToBack, win)
#define WTF(win) IntuiOp(WindowToFront, win)
#define WACT(win) IntuiOp((void (*)(APTR))ActivateWindow, win)
#define STB(scr) IntuiOp(MyScreenToBack, scr)
#define STF(scr) IntuiOp(ScreenToFront, scr)
static void __regargs
IntuiOp (void (*routine) (APTR), APTR parameter)
{
BYTE oldpri = SetTaskPri (thistask, 21);
intui_routine = routine;
intui_parameter = parameter;
Signal (thistask, intuiopsigflag);
SetTaskPri (thistask, oldpri);
}
/* pattern-matching on screen/window titles */
#define IsXXXScreen(scr, pat) (scr && (!scr->Title || MatchPattern(pat, scr->Title)))
#define IsClickScreen(scr) IsXXXScreen(scr, clickscrpat)
#define IsAutoScreen(scr) IsXXXScreen(scr, autoscrpat)
#define IsXXXWindow(win, pat) (!win->Title || MatchPattern(pat, win->Title))
#define IsPopWindow(win) IsXXXWindow(win,popwinpat)
#define IsClickWindow(win) IsXXXWindow(win,clickwinpat)
#define INTERRUPT void __interrupt __saveds
/* when is a window safe to bring to front and not already at front? */
#define OkayToPop(win) (!win->ReqCount && !(win->Flags & (WFLG_MENUSTATE|WFLG_BACKDROP)) \
&& win->WLayer->ClipRect && win->WLayer->ClipRect->Next)
/* WindowToFront only if no requester, not backdrop, not already front... */
static void __regargs
PopToFront (struct Window *win)
{
/* want to avoid popping immediately after mousebutton/keyboard */
if (misspop)
misspop = FALSE;
else if (OkayToPop (win))
{
/* Does it pass pattern? */
if (IsPopWindow (win))
WTF (win);
}
}
/* modified from DMouse */
/* expects multitasking to be Forbid()en */
static struct Screen *mousescr; /* the screen under the mouse */
void
ScreenUnderMouse( void )
{
for (mousescr = IntuitionBase->FirstScreen ;
mousescr && mousescr->TopEdge > 0 && mousescr->MouseY < 0;
mousescr = mousescr->NextScreen);
}
static struct Window *
WindowUnderMouse ( void )
{
struct Layer *layer = NULL;
for (mousescr = IntuitionBase->FirstScreen ;
mousescr && mousescr->TopEdge > 0 && mousescr->MouseY < 0;
mousescr = mousescr->NextScreen);
if (mousescr)
layer = WhichLayer(&mousescr->LayerInfo, mousescr->MouseX, mousescr->MouseY);
return (layer ? (struct Window *) layer->Window : NULL);
}
/* does active window have an active string gadget? */
static BOOL __regargs
StrGadgetActive (struct Window *w)
{
struct Gadget *g = w->FirstGadget;
for (; g; g = g->NextGadget)
if ((g->GadgetType & STRGADGET) && (g->Flags & GFLG_SELECTED))
return TRUE;
return FALSE;
}
/* activate window under mouse */
/* context sensitive; why tells routine how to behave */
/* can be AUTO, KEY, SCREEN, RMBACT */
#define AW IntuitionBase->ActiveWindow
#define AWS IntuitionBase->ActiveWindow->WScreen
#define FS IntuitionBase->FirstScreen
#define FSW IntuitionBase->FirstScreen->FirstWindow
void __regargs
ActivateMouseWindow (BYTE why)
{
struct Window *win;
BOOL forbidden = TRUE;
Forbid ();
if (win = WindowUnderMouse ()) /* window exists to activate */
{
/* either window is not active or auto-activating - need to pop? */
if (win->Flags & WFLG_WINDOWACTIVE) /* already active - needs popped? */
{
if (why == AUTO && autopop && IsAutoScreen (win->WScreen))
{
Permit (), forbidden = FALSE;
PopToFront (win);
}
}
else if (why != AUTO || IsAutoScreen (win->WScreen))
{
/* window is not active, should we try to activate it? */
/* AW is IntuitionBase->ActiveWindow */
if (!AW ||
!(AW->Flags & WFLG_MENUSTATE) && /* not showing menus */
!(why == KEY && StrGadgetActive (AW))) /* no str gad active */
{
/* finally... */
Permit (), forbidden = FALSE;
/* do autopop? */
if (why == AUTO && autopop)
PopToFront (win);
if (why == KEY)
ActivateWindow (win); /* need this to avoid losing keys */
else
WACT (win); /* ...activate window */
}
}
}
else
/* no window under mouse... */
{
if (mousescr && mousescr->FirstWindow &&
((why == SCREEN) || (why == RMBACT && AW && AWS != mousescr)))
{
Permit (), forbidden = FALSE;
WACT (mousescr->FirstWindow); /* ...activate window */
}
}
if (forbidden)
Permit ();
}
static UWORD __chip posctldata[4];
static struct SimpleSprite simplesprite =
{posctldata, 0, 0, 0, 0};
static BOOL mouseoff; /* is mouse off? (MB_SPRITES only) */
static void __inline
TurnMouseOn () /* restore mouse-pointer */
{
if (mouseblank == MB_SPRITES) /* really dirty blanking */
{ /* but guaranteed to work... */
if (mouseoff)
{
Forbid ();
WaitTOF ();
ON_SPRITE;
Permit ();
}
}
/* else using FreeSprite solution - unblanks when needed */
mouseoff = FALSE;
}
static void __inline
TurnMouseOff () /* blank mouse-pointer */
{
if (!mouseoff) /* no point in turning it off twice... */
{
Forbid ();
if (mouseblank == MB_SPRITES)
{
WaitTOF ();
OFF_SPRITE;
custom.spr[0].dataa = custom.spr[0].datab = 0;
}
else
{
FreeSprite (0);
GetSprite (&simplesprite, 0);
}
Permit ();
mouseoff = TRUE;
}
}
static BOOL blanked;
static struct Screen *blankscr;
/* blank display, by putting up a black screen */
/* this screen's displaymode is cloned from front screen */
void
BlankScreen ()
{
ULONG modeid = INVALID_ID;
if (blankscr)
ScreenToFront (blankscr);
else
{
Forbid ();
if (FS)
modeid = GetVPModeID (&(FS->ViewPort));
Permit ();
if (modeid == INVALID_ID)
modeid = LORES_KEY;
if (blankscr = OpenScreenTags (NULL, SA_Depth, 1,
SA_Quiet, TRUE,
SA_Behind, TRUE,
SA_DisplayID, modeid,
TAG_DONE))
{
SetRGB4 (&blankscr->ViewPort, 0, 0, 0, 0);
ScreenToFront (blankscr);
blanked = TRUE;
}
}
OFF_SPRITE;
custom.spr[0].dataa = custom.spr[0].datab = 0;
}
/* unblank display, i.e. close our screen */
void
UnBlankScreen ()
{
if (blankscr)
CloseScreen (blankscr);
blankscr = NULL;
blanked = FALSE;
ON_SPRITE;
}
#define ALL_BUTTONS (IEQUALIFIER_LEFTBUTTON|IEQUALIFIER_RBUTTON|IEQUALIFIER_MIDBUTTON)
#define KEY_QUAL (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT \
|IEQUALIFIER_CONTROL \
|IEQU